# -*- coding: utf-8 -*-
"""
Created on Sun Nov  4 14:13:11 2018

@author: Sz-wyz
"""
#协同过滤 - 爱你所爱 中二的名字--
from math import sqrt

#字典中为不同的人对不同乐队的打分 
#此例用于寻找相似用户
users = {"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2.0},
         "Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, "Phoenix": 2.0, "Slightly Stoopid": 3.5, "Vampire Weekend": 3.0},
         "Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0},
         "Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, "Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 2.0},
         "Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, "The Strokes": 4.0, "Vampire Weekend": 1.0},
         "Jordyn":  {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, "Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 4.0},
         "Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0, "Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0},
         "Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0}
        }

def manhattan(rating1,rating2):#计算曼哈顿距离
    distance = 0
    commonRatings = False
    for key in rating1:
        if key in rating2:#针对相同乐队
            distance += abs(rating1[key]-rating2[key])
            commonRatings = True
    if commonRatings:
        return distance
    else:
        return -1

def computeNearestNeighbor(username,users):#寻找最近用户的函数
    distances = []
    for user in users:
        if user != username:
            distance = manhattan(users[user],users[username])
            distances.append((distance,user))
    distances.sort()
    #实际上，是按照相似度从高到低的次序返回用户列表
    return distances
    
'''
推荐 假设为Hailey进行推荐，找到她最近的邻居，是Veronica
查找Veronica评过级为Hailey没有评级的乐队将它推荐给Hailey
'''
def recommend(username,users):
    nearest = computeNearestNeighbor(username,users)[0][1]
    recommendatios = []
    neighborRatings = users[nearest]
    userRatings = users[username]
    for artist in neighborRatings:
        if not artist in userRatings:
            recommendatios.append((artist,neighborRatings[artist]))
    return sorted(recommendatios,key = lambda artistTuple : artistTuple[1],\
                  reverse = True)#进行排列

print(recommend('Hailey',users))
print(recommend('Chan',users))
print(recommend('Sam',users))














    



